package com.github.cakin.shiro.chapter11.dao;

import com.github.cakin.shiro.chapter11.JdbcTemplateUtils;
import com.github.cakin.shiro.chapter11.entity.Role;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
import org.springframework.jdbc.support.GeneratedKeyHolder;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import static com.github.cakin.shiro.chapter11.constant.Constant.NUM2;
import static com.github.cakin.shiro.chapter11.constant.Constant.NUM3;

/**
 * @className: RoleDaoImpl
 * @description: 角色访问层实现类
 * @date: 2020/5/19
 * @author: cakin
 */
public class RoleDaoImpl implements RoleDao {
    /**
     * 创建一个 jdbcTemplate
     */
    private JdbcTemplate jdbcTemplate = JdbcTemplateUtils.jdbcTemplate();

    /**
     * 功能描述：创建角色
     *
     * @param role 角色
     * @return Role 角色
     * @author cakin
     * @date 2020/5/19
     */
    public Role createRole( final Role role ) {
        final String sql = "insert into sys_roles(role, description, available) values(?,?,?)";

        GeneratedKeyHolder keyHolder = new GeneratedKeyHolder();
        jdbcTemplate.update(new PreparedStatementCreator() {
            public PreparedStatement createPreparedStatement( Connection connection ) throws SQLException {
                PreparedStatement psst = connection.prepareStatement(sql, new String[]{"id"});
                psst.setString(1, role.getRole());
                psst.setString(NUM2, role.getDescription());
                psst.setBoolean(NUM3, role.getAvailable());
                return psst;
            }
        }, keyHolder);
        role.setId(keyHolder.getKey().longValue());

        return role;
    }

    /**
     * 功能描述：删除角色
     *
     * @param roleId 角色id
     * @author cakin
     * @date 2020/5/19
     */
    public void deleteRole( Long roleId ) {
        // 首先把和role关联的sys_users_roles表数据删掉
        String sql = "delete from sys_users_roles where role_id=?";
        jdbcTemplate.update(sql, roleId);

        sql = "delete from sys_roles where id=?";
        jdbcTemplate.update(sql, roleId);
    }

    /**
     * 功能描述：添加角色-权限之间关系
     *
     * @param roleId        角色id
     * @param permissionIds 权限id列表
     * @author cakin
     * @date 2020/5/19
     */
    public void correlationPermissions( Long roleId, Long... permissionIds ) {
        if (permissionIds == null || permissionIds.length == 0) {
            return;
        }
        String sql = "insert into sys_roles_permissions(role_id, permission_id) values(?,?)";
        for (Long permissionId : permissionIds) {
            if (!exists(roleId, permissionId)) {
                jdbcTemplate.update(sql, roleId, permissionId);
            }
        }
    }


    /**
     * 功能描述：移除角色-权限之间关系
     *
     * @param roleId        角色id
     * @param permissionIds 权限id列表
     * @author cakin
     * @date 2020/5/19
     * @description:
     */
    public void uncorrelationPermissions( Long roleId, Long... permissionIds ) {
        if (permissionIds == null || permissionIds.length == 0) {
            return;
        }
        String sql = "delete from sys_roles_permissions where role_id=? and permission_id=?";
        for (Long permissionId : permissionIds) {
            if (exists(roleId, permissionId)) {
                jdbcTemplate.update(sql, roleId, permissionId);
            }
        }
    }

    /**
     * 功能描述： 判断 （role_id，permission_id）关系是否存在于sys_roles_permissions表
     *
     * @param roleId 角色id
     * @param permissionId 权限id
     * @return boolean
     * @author cakin
     * @date 2020/5/19
     * @description:
     */
    private boolean exists( Long roleId, Long permissionId ) {
        String sql = "select count(1) from sys_roles_permissions where role_id=? and permission_id=?";
        return jdbcTemplate.queryForObject(sql, Integer.class, roleId, permissionId) != 0;
    }

}
